<template>
  <div class="share-page">
    <header class="share-header">
      <div class="logo">
        <img :src="logoImg" alt="Logo" class="logo-img" />
        <span class="logo-text">云盘分享</span>
      </div>
    </header>

    <main class="share-content">
      <div class="share-info">
        <!-- 验证码页面 -->
        <template v-if="!shareInfo?.isChecked">
          <div class="user-info">
            <a-avatar :size="32" :src="IMAGE_PREFIX + shareInfo?.avatar" />
            <span class="username">{{ shareInfo?.nickName }}</span>
          </div>
          <div class="share-time">
            分享于 {{ formatDate(shareInfo?.shareTime, 'YYYY-MM-DD HH:mm:ss') }}
          </div>

          <div class="file-info">
            <div
              class="file-icon"
              :class="{
                'has-cover':
                  shareInfo?.fileCover && (shareInfo?.fileType === 1 || shareInfo?.fileType === 3),
              }"
            >
              <!-- 复用文件图标渲染逻辑 -->
              <img v-if="shareInfo?.folderType === 1" :src="folderIcon" alt="文件夹" />
              <template v-else>
                <img
                  :src="getFileTypeIcon(shareInfo?.fileType, shareInfo?.fileCover)"
                  :alt="shareInfo?.fileName"
                />
                <div class="video-overlay" v-if="shareInfo?.fileType === 1 && shareInfo?.fileCover">
                  <i class="video-play-icon"></i>
                </div>
              </template>
            </div>
            <div class="file-meta">
              <div class="file-name">{{ shareInfo?.fileName }}</div>
              <div class="expire-time">
                有效期至：{{ formatDate(shareInfo?.expireTime, 'YYYY-MM-DD HH:mm:ss') }}
              </div>
            </div>
          </div>

          <div class="verify-section">
            <p class="verify-tip">请输入提取码访问分享内容</p>
            <a-input
              v-model:value="shareCode"
              placeholder="请输入5位提取码"
              :maxLength="5"
              class="verify-input"
            />
            <a-button type="primary" :loading="verifying" @click="handleVerify" class="verify-btn">
              验证提取码
            </a-button>
            <p class="security-tip">请妥善保管提取码，避免隐私泄露</p>
          </div>
        </template>

        <!-- 文件列表页面 -->
        <template v-else>
          <div class="file-list-header">
            <div class="user-info">
              <a-avatar :size="32" :src="IMAGE_PREFIX + shareInfo?.avatar" />
              <span class="username">{{ shareInfo?.nickName }}</span>
              <span class="share-time"
                >分享于 {{ formatDate(shareInfo?.shareTime, 'YYYY-MM-DD HH:mm:ss') }}</span
              >
            </div>
            <!-- 只有非当前用户才显示保存按钮 -->
            <div v-if="!shareInfo?.currentUser" class="save-action">
              <a-tooltip placement="left" title="请先选择要保存的文件">
                <a-button
                  type="primary"
                  @click="handleBatchSaveToSpace"
                  :disabled="!selectedFiles.length"
                >
                  <template #icon><SaveOutlined /></template>
                  保存到我的网盘
                </a-button>
              </a-tooltip>
            </div>
          </div>

          <a-table
            :row-selection="
              !shareInfo?.currentUser
                ? {
                    selectedRowKeys: selectedFiles,
                    onChange: onSelectChange,
                    type: 'checkbox',
                  }
                : false
            "
            :row-key="record => record.fileId"
            :columns="fileColumns"
            :data-source="fileList"
            :loading="loading"
            :scroll="{ x: 1000 }"
            :locale="{
              emptyText: '暂无分享文件',
            }"
            class="file-table"
          >
            <template #bodyCell="{ column, record }">
              <!-- 图标列 -->
              <template v-if="column.key === 'icon'">
                <div
                  class="file-icon"
                  :class="{
                    'has-cover':
                      record.fileCover && (record.fileType === 1 || record.fileType === 3),
                  }"
                >
                  <img v-if="record.folderType === 1" :src="folderIcon" alt="文件夹" />
                  <template v-else>
                    <img
                      :src="getFileTypeIcon(record.fileType, record.fileCover)"
                      :alt="record.fileName"
                    />
                    <div class="video-overlay" v-if="record.fileType === 1 && record.fileCover">
                      <i class="video-play-icon"></i>
                    </div>
                  </template>
                </div>
              </template>

              <!-- 文件名列 -->
              <template v-if="column.key === 'name'">
                <span class="file-name-cell">{{ record.fileName }}</span>
              </template>

              <!-- 大小列 -->
              <template v-if="column.key === 'size'">
                <span>{{ formatFileSize(record.fileSize) }}</span>
              </template>

              <!-- 修改时间列 -->
              <template v-if="column.key === 'time'">
                <span>{{ record.shareTime }}</span>
              </template>

              <!-- 操作列 -->
              <template v-if="column.key === 'action'">
                <div class="action-cell">
                  <a-button type="link" @click="handleDownload(record)">
                    <template #icon><DownloadOutlined /></template>
                    下载
                  </a-button>
                  <a-button
                    v-if="!shareInfo?.currentUser"
                    type="link"
                    @click="handleSaveToSpace(record)"
                  >
                    <template #icon><SaveOutlined /></template>
                    保存
                  </a-button>
                </div>
              </template>
            </template>
          </a-table>
        </template>
      </div>
    </main>

    <!-- 保存到网盘对话框 -->
    <a-modal
      v-model:open="saveModalVisible"
      title="保存到网盘"
      @ok="handleSaveConfirm"
      :confirmLoading="saving"
      :width="720"
      :style="{ top: '20px' }"
      destroyOnClose
      class="save-modal"
      okText="确定"
      cancelText="取消"
    >
      <template v-if="!isLogin">
        <div class="login-tip">
          <p>请先登录后再保存文件</p>
          <a-button type="primary" @click="handleLogin">去登录</a-button>
        </div>
      </template>
      <template v-else>
        <div class="folder-select-container">
          <div class="folder-header">
            <span class="folder-title">选择保存位置</span>
            <span class="selected-count" v-if="selectedFiles.length">
              已选择 {{ selectedFiles.length }} 个文件
            </span>
          </div>

          <div class="folder-tree-container">
            <div class="folder-title">选择目标文件夹</div>
            <a-tree
              v-if="folderTree.length > 0"
              :tree-data="folderTree"
              :selectedKeys="[selectedFolder]"
              @select="handleFolderSelect"
              :showLine="true"
              :showIcon="true"
              :fieldNames="{
                title: 'title',
                key: 'value',
                children: 'children',
              }"
            >
              <template #icon="{ selected }">
                <FolderOutlined v-if="!selected" style="color: #faa131" />
                <FolderOpenOutlined v-else style="color: #faa131" />
              </template>
              <template #switcherIcon="{ expanded }">
                <CaretDownOutlined v-if="expanded" />
                <CaretRightOutlined v-else />
              </template>
            </a-tree>

            <div v-else class="empty-folder-tip">
              <FolderOutlined style="font-size: 24px; color: #faa131; margin-bottom: 8px" />
              <p>暂无自定义文件夹，文件将保存到"全部"</p>
            </div>
          </div>
        </div>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted, computed } from 'vue'
  import { useRoute } from 'vue-router'
  import { IMAGE_PREFIX } from '@/config/constants'
  import { message } from 'ant-design-vue'
  import {
    DownloadOutlined,
    SaveOutlined,
    FolderOutlined,
    FolderOpenOutlined,
    CaretDownOutlined,
    CaretRightOutlined,
  } from '@ant-design/icons-vue'
  import { formatDate } from '@/utils/date'
  import {
    getShareInfoUsingPost,
    checkShareCodeUsingPost,
    loadFileListUsingPost,
    saveShareUsingPost,
    loadMyFolderUsingPost,
    createDownloadUrlUsingPost,
  } from '@/api/fenxiangjiekou'
  import dayjs from 'dayjs'

  // 导入图标资源
  import folderIcon from '@/assets/files/文件夹.png'
  import imageIcon from '@/assets/files/图片.png'
  import videoIcon from '@/assets/files/视频.png'
  import audioIcon from '@/assets/files/音乐.png'
  import pdfIcon from '@/assets/files/pdf.png'
  import docIcon from '@/assets/files/doc.png'
  import excelIcon from '@/assets/files/excel.png'
  import txtIcon from '@/assets/files/txt.png'
  import codeIcon from '@/assets/files/code.png'
  import zipIcon from '@/assets/files/zip.png'
  import otherIcon from '@/assets/files/其他.png'
  import logoImg from '@/assets/logo.png'

  const route = useRoute()

  // 状态变量
  const shareInfo = ref<any>(null)
  const shareCode = ref('')
  const verifying = ref(false)
  const loading = ref(false)
  const fileList = ref<any[]>([])
  const selectedFiles = ref<string[]>([])
  const currentFolder = ref('0')

  // 保存到网盘相关
  const saveModalVisible = ref(false)
  const saving = ref(false)
  const selectedFolder = ref<string>()
  const folderTree = ref<any[]>([])

  // 计算属性
  const isLogin = computed(() => shareInfo.value?.isLogin)

  // 初始化
  onMounted(async () => {
    const shareId = route.params.id as string
    if (!shareId) {
      message.error('分享ID不能为空')
      return
    }

    try {
      const res = await getShareInfoUsingPost({ shareId })
      if (res.data?.code === 200) {
        shareInfo.value = res.data.data
        // 如果已经验证过分享码,直接加载文件列表
        if (shareInfo.value.isChecked) {
          loadFiles()
        }
      } else {
        message.error(res.data?.message || '获取分享信息失败')
      }
    } catch {
      message.error('获取分享信息失败')
    }
  })

  // 验证提取码
  const handleVerify = async () => {
    if (!shareCode.value) {
      message.warning('请输入提取码')
      return
    }

    verifying.value = true
    try {
      const res = await checkShareCodeUsingPost({
        shareId: route.params.id as string,
        code: shareCode.value,
      })

      if (res.data?.code === 200) {
        shareInfo.value.isChecked = true
        // 验证成功后立即加载文件列表
        loadFiles()
      } else {
        message.error(res.data?.message || '提取码验证失败')
      }
    } catch {
      message.error('提取码验证失败')
    } finally {
      verifying.value = false
    }
  }

  // 加载文件列表
  const loadFiles = async () => {
    loading.value = true
    try {
      const res = await loadFileListUsingPost({
        shareId: route.params.id as string,
        filePid: currentFolder.value,
        pageNo: 1,
        pageSize: 100,
      })

      if (res.data?.code === 200) {
        // 处理单文件数据结构
        const fileData = res.data.data
        if (fileData) {
          fileList.value = [
            {
              fileId: fileData.fileId,
              fileName: fileData.fileName,
              fileSize: Number(fileData.fileSize),
              shareTime: fileData.shareTime,
              fileType: fileData.fileType,
              fileCover: fileData.fileCover,
              folderType: fileData.folderType,
              fileCategory: fileData.fileCategory,
            },
          ]
        } else {
          fileList.value = []
        }
      } else {
        message.error(res.data?.message || '获取文件列表失败')
      }
    } catch {
      message.error('获取文件列表失败')
    } finally {
      loading.value = false
    }
  }

  // 文件选择变化
  const onSelectChange = (selectedRowKeys: string[]) => {
    selectedFiles.value = selectedRowKeys
  }

  // 下载文件
  const handleDownload = async (file: any) => {
    try {
      // 如果是通过表格行的下载按钮触发，使用当前文件ID
      const fileIds = file ? [file.fileId] : selectedFiles.value

      if (!fileIds.length) {
        message.warning('请选择要下载的文件')
        return
      }

      // 创建下载链接
      const res = await createDownloadUrlUsingPost({
        shareId: route.params.id as string,
        shareFileIds: fileIds.join(','),
      })

      if (res.data?.code === 200) {
        // 对每个文件ID执行下载
        for (const fileId of fileIds) {
          try {
            // 构建下载URL
            const downloadUrl = `/api/showShare/download/${route.params.id}/${fileId}`

            // 使用fetch API获取文件流
            const response = await fetch(downloadUrl)
            if (!response.ok) {
              throw new Error(`下载失败: ${response.statusText}`)
            }

            // 获取文件名
            const contentDisposition = response.headers.get('content-disposition')
            let filename = ''
            if (contentDisposition) {
              const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition)
              if (matches != null && matches[1]) {
                filename = decodeURIComponent(matches[1].replace(/['"]/g, ''))
              }
            }
            // 如果无法从header获取文件名，使用默认文件名
            if (!filename) {
              filename = file ? file.fileName : `download-${fileId}`
            }

            // 将响应转换为blob
            const blob = await response.blob()

            // 创建下载链接并触发下载
            const downloadLink = document.createElement('a')
            downloadLink.href = window.URL.createObjectURL(blob)
            downloadLink.download = filename
            document.body.appendChild(downloadLink)
            downloadLink.click()
            document.body.removeChild(downloadLink)
            window.URL.revokeObjectURL(downloadLink.href)
          } catch (error) {
            console.error('文件下载失败:', error)
            message.error(`文件下载失败: ${error.message}`)
          }
        }
      } else {
        message.error(res.data?.message || '创建下载链接失败')
      }
    } catch {
      message.error('下载失败')
    }
  }

  // 保存到网盘
  const handleSaveToSpace = async (file: any) => {
    if (!shareInfo.value?.isLogin) {
      message.warning('请先登录')
      return
    }
    selectedFiles.value = [file.fileId]
    // 打开对话框前先加载文件夹列表
    await loadMyFolders()
  }

  // 加载我的文件夹
  const loadMyFolders = async (pid = '0') => {
    try {
      const res = await loadMyFolderUsingPost(pid)
      if (res.data?.code === 200) {
        if (pid === '0') {
          // 如果是加载根目录，直接设置整个树
          folderTree.value = formatFolderTree(res.data.data || [])
          // 如果没有文件夹，添加默认的"全部"选项
          if (!res.data.data || res.data.data.length === 0) {
            folderTree.value = [
              {
                value: '0',
                title: '全部',
                isLeaf: true,
              },
            ]
          }
          saveModalVisible.value = true
        } else {
          // 如果是加载子文件夹，更新当前节点的children
          const updateTreeData = (list, pid, children) => {
            return list.map(node => {
              if (node.value === pid) {
                return {
                  ...node,
                  children: children.map(child => ({
                    value: child.fileId,
                    title: child.fileName,
                    isLeaf: false,
                  })),
                }
              }
              if (node.children) {
                return {
                  ...node,
                  children: updateTreeData(node.children, pid, children),
                }
              }
              return node
            })
          }
          folderTree.value = updateTreeData(folderTree.value, pid, res.data.data || [])
        }
      } else {
        message.error(res.data?.message || '获取文件夹列表失败')
      }
    } catch {
      message.error('获取文件夹列表失败')
    }
  }

  // 保存确认
  const handleSaveConfirm = async () => {
    if (!selectedFolder.value && selectedFolder.value !== '0') {
      message.warning('请选择保存位置')
      return
    }

    saving.value = true
    try {
      const res = await saveShareUsingPost({
        shareId: route.params.id as string,
        shareFileIds: selectedFiles.value.join(','),
        myFolderId: selectedFolder.value,
      })

      if (res.data?.code === 200) {
        message.success('保存成功')
        saveModalVisible.value = false
        // 清空选择
        selectedFiles.value = []
        selectedFolder.value = undefined
      } else {
        message.error(res.data?.message || '保存失败')
      }
    } catch {
      message.error('保存失败')
    } finally {
      saving.value = false
    }
  }

  // 工具函数
  const formatFileSize = (size: number) => {
    if (!size || isNaN(size)) return '0 B'

    const units = ['B', 'KB', 'MB', 'GB', 'TB']
    let index = 0
    let fileSize = size

    while (fileSize >= 1024 && index < units.length - 1) {
      fileSize /= 1024
      index++
    }

    return `${fileSize.toFixed(fileSize >= 10 || index === 0 ? 0 : 1)} ${units[index]}`
  }

  // 获取文件图标的方法
  const getFileTypeIcon = (fileType: number, fileCover?: string) => {
    if (fileType === 3 && fileCover) return fileCover // 图片且有封面
    if (fileType === 1 && fileCover) return fileCover // 视频且有封面

    const iconMap = {
      1: videoIcon, // 视频
      2: audioIcon, // 音频
      3: imageIcon, // 图片
      4: pdfIcon, // PDF
      5: docIcon, // Word
      6: excelIcon, // Excel
      7: txtIcon, // 文本
      8: codeIcon, // 代码
      9: zipIcon, // 压缩包
    }
    return iconMap[fileType] || otherIcon
  }

  const fileColumns = [
    {
      title: '选择',
      dataIndex: 'icon',
      key: 'icon',
      width: 70,
      fixed: 'left',
    },
    {
      title: '文件名',
      dataIndex: 'fileName',
      key: 'name',
      ellipsis: true,
      width: 450,
    },
    {
      title: '大小',
      dataIndex: 'fileSize',
      key: 'size',
      width: 120,
      align: 'right',
    },
    {
      title: '分享时间',
      dataIndex: 'shareTime',
      key: 'time',
      width: 180,
      align: 'center',
      customRender: ({ text }) => {
        return text ? formatDate(text, 'YYYY-MM-DD HH:mm:ss') : '-'
      },
    },
    {
      title: '操作',
      key: 'action',
      width: 140,
      fixed: 'right',
      align: 'center',
    },
  ]

  // 批量保存到网盘
  const handleBatchSaveToSpace = async () => {
    if (!shareInfo.value?.isLogin) {
      message.warning('请先登录')
      return
    }
    if (!selectedFiles.value.length) {
      message.warning('请选择要保存的文件')
      return
    }
    // 打开对话框前先加载文件夹列表
    await loadMyFolders()
  }

  // 格式化文件夹树形结构
  const formatFolderTree = (folders: any[]) => {
    return folders.map(folder => ({
      value: folder.fileId,
      title: folder.fileName,
      isLeaf: false,
    }))
  }

  // 处理文件夹选择
  const handleFolderSelect = async (selectedKeys, info) => {
    selectedFolder.value = selectedKeys[0]
    // 点击文件夹时直接加载子文件夹
    if (info.selected && info.node && (!info.node.children || info.node.children.length === 0)) {
      await loadMyFolders(info.node.value)
    }
  }

  // 处理登录
  const handleLogin = () => {
    // 实现登录逻辑
  }

  const formatDateSmart = (val: any) => {
    if (!val) return '-'
    // 10位数字（秒级时间戳）自动转为毫秒
    if (/^\d{10}$/.test(String(val))) {
      return dayjs(Number(val) * 1000).format('YYYY-MM-DD HH:mm:ss')
    }
    // 13位数字（毫秒级时间戳）
    if (/^\d{13}$/.test(String(val))) {
      return dayjs(Number(val)).format('YYYY-MM-DD HH:mm:ss')
    }
    // 其它情况尝试直接格式化
    return dayjs(val).isValid() ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : '-'
  }
</script>

<style scoped>
  .share-page {
    min-height: 100vh;
    background-color: #f0f2f5;
    color: rgba(0, 0, 0, 0.85);
    position: relative;
    z-index: 1;
  }

  .share-header {
    height: 64px;
    padding: 0 50px;
    display: flex;
    align-items: center;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    justify-content: space-between;
  }

  .logo {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .logo-img {
    width: 32px;
    height: 32px;
    object-fit: contain;
  }

  .logo-text {
    font-size: 20px;
    color: rgba(0, 0, 0, 0.85);
    font-weight: 600;
  }

  .share-content {
    display: flex;
    justify-content: center;
    padding: 104px 20px 40px;
  }

  .share-info {
    width: 1200px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    padding: 24px;
  }

  .user-info {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
  }

  .username {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);
    font-weight: 500;
  }

  .share-time {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.45);
    margin-bottom: 32px;
  }

  .file-info {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 24px;
    background: #fafafa;
    border-radius: 8px;
    margin-bottom: 40px;
    border: 1px solid #f0f0f0;
  }

  .file-icon {
    width: 40px;
    height: 40px;
    border-radius: 4px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f5f7fa;
    border: 1px solid #f0f0f0;
  }

  .file-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .file-icon.has-cover img {
    object-fit: cover;
  }

  .video-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .video-play-icon {
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 10px 0 10px 16px;
    border-color: transparent transparent transparent #ffffff;
  }

  .file-meta {
    flex: 1;
  }

  .file-name {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);
    margin-bottom: 8px;
    font-weight: 500;
  }

  .expire-time {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.45);
  }

  .verify-section {
    text-align: center;
    padding: 0 60px;
  }

  .verify-tip {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);
    margin-bottom: 24px;
    font-weight: 500;
  }

  .verify-input {
    margin-bottom: 24px;
  }

  :deep(.ant-input) {
    height: 48px;
    font-size: 16px;
    border-radius: 8px;
    border: 1px solid #d9d9d9;
    background: #fff;
    color: rgba(0, 0, 0, 0.85);
    text-align: center;
  }

  :deep(.ant-input:hover) {
    border-color: #40a9ff;
  }

  :deep(.ant-input:focus) {
    border-color: #40a9ff;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  }

  :deep(.ant-input::placeholder) {
    color: rgba(0, 0, 0, 0.25);
  }

  .verify-btn {
    width: 100%;
    height: 48px;
    font-size: 16px;
    border-radius: 8px;
    background: #1890ff;
    border: none;
    margin-bottom: 24px;
    font-weight: 500;
  }

  .verify-btn:hover {
    background: #40a9ff;
  }

  .verify-btn:active {
    background: #096dd9;
  }

  .security-tip {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.45);
  }

  .login-tip {
    text-align: center;
    padding: 32px;
  }

  .login-tip p {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);
    margin-bottom: 24px;
  }

  .file-list-section {
    margin-top: 24px;
  }

  .file-table {
    background: #fff;
    border-radius: 8px;
  }

  :deep(.ant-table) {
    border-radius: 8px;
    overflow: hidden;
  }

  :deep(.ant-table-thead > tr > th) {
    background: #fafafa;
    font-weight: 500;
    padding: 14px !important;
    border-bottom: 1px solid #f0f0f0;
    white-space: nowrap;
  }

  :deep(.ant-table-tbody > tr > td) {
    padding: 14px !important;
    white-space: nowrap;
  }

  :deep(.ant-table-cell) {
    transition: background 0.3s;
  }

  .file-name-cell {
    color: rgba(0, 0, 0, 0.85);
    font-weight: 500;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .file-name-cell:hover {
    color: #1890ff;
  }

  .action-cell {
    display: flex;
    gap: 12px;
    justify-content: center;
  }

  :deep(.ant-btn-link) {
    padding: 4px 8px;
    height: 28px;
    font-size: 14px;
  }

  :deep(.ant-btn-link:hover) {
    color: #40a9ff;
    background: #f5f5f5;
    border-radius: 4px;
  }

  .save-action {
    margin-bottom: 16px;
    display: flex;
    justify-content: flex-end;
  }

  :deep(.ant-table-selection) {
    width: 48px;
  }

  .file-list-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
  }

  .file-list-header .user-info {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .file-list-header .share-time {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.45);
    margin-left: 12px;
  }

  .folder-select-container {
    .folder-header {
      padding: 16px 24px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid #f0f0f0;

      .folder-title {
        font-size: 14px;
        color: rgba(0, 0, 0, 0.85);
        font-weight: 500;
      }

      .selected-count {
        font-size: 13px;
        color: rgba(0, 0, 0, 0.45);
      }
    }

    .folder-tree-container {
      padding: 24px;
      min-height: 360px;
      max-height: 480px;
      overflow-y: auto;

      .folder-title {
        font-size: 14px;
        color: #333;
        margin-bottom: 16px;
      }

      :deep(.ant-tree) {
        background: transparent;
      }

      :deep(.ant-tree-node-content-wrapper) {
        padding: 8px 12px;
        transition: all 0.3s;
        border-radius: 4px;

        &:hover {
          background-color: #e6f4ff;
        }

        &.ant-tree-node-selected {
          background-color: #e6f4ff;
        }
      }

      :deep(.ant-tree-switcher) {
        width: 24px;
        height: 24px;
        line-height: 24px;
      }

      :deep(.ant-tree-switcher-icon) {
        color: #999;
        font-size: 12px;
      }

      :deep(.ant-tree-title) {
        font-size: 14px;
        color: #333;
        margin-left: 8px;
      }
    }

    .empty-folder-tip {
      text-align: center;
      padding: 32px 16px;
      color: #666;

      p {
        margin-top: 8px;
        font-size: 14px;
      }
    }
  }

  .save-modal {
    :deep(.ant-modal-content) {
      border-radius: 12px;
      overflow: hidden;
    }

    :deep(.ant-modal-header) {
      padding: 20px 24px;
      border-bottom: 1px solid #f0f0f0;

      .ant-modal-title {
        font-size: 16px;
        font-weight: 600;
      }
    }

    :deep(.ant-modal-body) {
      padding: 0;
    }

    :deep(.ant-modal-footer) {
      padding: 16px 24px;
      border-top: 1px solid #f0f0f0;

      .ant-btn {
        min-width: 88px;
        height: 36px;
        font-size: 14px;
        border-radius: 4px;

        &-primary {
          background: #1890ff;
        }
      }
    }
  }

  :deep(.ant-table-empty .ant-table-tbody > tr.ant-table-placeholder) {
    height: 400px;
  }

  :deep(.ant-table-empty .ant-table-tbody > tr.ant-table-placeholder:hover > td) {
    background: #fff;
  }

  :deep(.ant-empty) {
    margin: 32px 0;
  }

  :deep(.ant-empty-image) {
    height: 160px;
  }

  :deep(.ant-empty-description) {
    color: rgba(0, 0, 0, 0.25);
    font-size: 14px;
  }

  :deep(.ant-table-cell) {
    white-space: nowrap;
    padding: 16px !important;
  }

  :deep(.ant-table-row) {
    height: 70px;
  }
</style>
